package pattern.strategy2;

/* HeadFirstForDesignPattern的鸭子案例 */
public class DuckDemo {
    public static void main(String[] args){
        Duck rubber = new RubberDuck();
        rubber.preformFly();
        rubber.preformQuark();

        //策略模式最强大的地方：可以在运行时动态修改策略组合
        rubber.setFy(new TrueFly());
        rubber.preformFly();
    }
}

/* 
    鸭子抽象类只放公共的方法
    以及策略的成员以及getter/setter
    以及使用策略的代理方法
 */
abstract class Duck {
    protected Flyable fy;
    protected Quarkable qk;

    //默认构造方法，交给子类重写

    public Flyable getFy() {
        return fy;
    }

    public void setFy(Flyable fy) {
        this.fy = fy;
    }

    public Quarkable getQk() {
        return qk;
    }

    public void setQk(Quarkable qk) {
        this.qk = qk;
    }

    //确定子类都拥有的功能，且功能是确定的，做默认实现
    public void swim() {
        System.out.println("swiming");
    }

    //确定子类都拥有的功能，功能不确定，留给子类重写
    public abstract void display();

    public void preformFly() {
        fy.fly();
    }

    public void preformQuark() {
        qk.quark();
    }
}

class RubberDuck extends Duck {
    public RubberDuck() {
        //对于一类产品，几种组合可以理解为产品簇
        this.fy = new CannotFly();
        this.qk = new SqueakQuark();
    }

    @Override
    public void display() {
        System.out.println("小黄鸭");        
    }  
}

class WildDuck extends Duck {

    public WildDuck() {
        this.fy = new TrueFly();
        this.qk = new QuaQuaQuark();
    }
    @Override
    public void display() {
        System.out.println("脖子绿，身体灰");        
    }

}

//策略接口及其实现类
interface Flyable {
    void fly();
}

class TrueFly implements Flyable {
    @Override
    public void fly() {
        System.out.println("我可是真飞");        
    }   
}

class CannotFly implements Flyable {
    @Override
    public void fly() {
        System.out.println("飞不起来");
    }
}

interface Quarkable {
    void quark();
}

class QuaQuaQuark implements Quarkable {
    @Override
    public void quark() {
        System.out.println("嘎嘎叫");
    }
}

class SqueakQuark implements Quarkable {
    @Override
    public void quark() {
        System.out.println("吱吱叫");
    }
}
